package com.ccloud.auth.core.handler;

import cn.hutool.core.util.ObjectUtil;
import com.ccloud.common.core.model.LoginVal;
import com.ccloud.auth.common.model.TokenConstant;
import com.ccloud.common.core.utils.OauthUtils;
import com.ccloud.common.core.constant.CacheConstants;
import com.ccloud.common.redis.cache.ZCache;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2RefreshToken;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.web.authentication.logout.LogoutHandler;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
@Slf4j
public class CLogoutHandler implements LogoutHandler {

    @Resource
    private TokenStore tokenStore;

    @Resource
    private ZCache zCache;

    @Override
    public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
        String accessToken = request.getHeader(TokenConstant.FULL_TOKEN);

        //移除 access_token 和 refresh_token
        revokeToken(accessToken);

    }

    /**
     * 注销token
     *
     * @param accessToken 有效的token
     * @author chentl
     * @version v1.0.0
     * @since 2:34 下午 2022/3/25
     **/
    private void revokeToken(String accessToken) {
        OAuth2AccessToken oAuth2AccessToken = tokenStore.readAccessToken(accessToken);
        if (oAuth2AccessToken != null) {
            tokenStore.removeAccessToken(oAuth2AccessToken);
            OAuth2RefreshToken oAuth2RefreshToken = oAuth2AccessToken.getRefreshToken();
            if (ObjectUtil.isNotNull(oAuth2RefreshToken)) {
                tokenStore.removeRefreshToken(oAuth2RefreshToken);
                tokenStore.removeAccessTokenUsingRefreshToken(oAuth2RefreshToken);
            }

            zCache.evict(CacheConstants.PREFIX_USER_TOKEN + accessToken);
            zCache.evict(CacheConstants.PREFIX_USER_SHIRO_CACHE + oAuth2AccessToken.getAdditionalInformation().get(TokenConstant.USER_ID));

            log.info("[oauth2] 登录用户: {} 已注销", oAuth2AccessToken.getAdditionalInformation().get(TokenConstant.USER_NAME));

        }


    }
}